#include <cstddef>
#include <iostream>
#include <memory>
#include <typeinfo>
#include <utility>
#include <cassert>

class Any
{
private:
    class holder
    {
    public:
        virtual ~holder(){}
        virtual const std::type_info& type() = 0;
        virtual holder *clone() = 0;
    };
    template<class T>
    class placeholder : public holder
    {
    public:
        placeholder(const T &val) : _val(val)
        {}
        virtual ~placeholder(){}
        //获取子类对象保存的数据类型
        virtual const std::type_info& type() override {return typeid(T);}
        //针对当前对象，克隆新的子类对象
        virtual holder *clone() override {return new placeholder<T>(_val);}

    public:
        T _val;
    };
    holder *_content;

private:
    void swap(Any& other) noexcept 
    {
        std::swap(this->_content, other._content);
    }
public:
    Any():_content(nullptr)
    {}
    template<class T>
    Any(const T &val) : _content(new placeholder<T>(val))
    {}
    Any(const Any &other):_content(other._content ? other._content->clone() : nullptr)
    {}
    Any(Any&& other) : _content(other._content) 
    {
        other._content = nullptr; 
    }
    ~Any()  {delete _content;}

    template<class T>
    T* get()
    {
        //类型校验
        if(_content && typeid(T) == _content->type())
        {
            auto ptr = dynamic_cast<placeholder<T>*>(_content);
            if(ptr != nullptr)
                return &(ptr->_val);          
        }
        return nullptr;
    }
    template<class T>
    Any& operator=(const T &val)
    {
        Any tmp(val);
        swap(tmp);
        return *this;
    }
    Any& operator=(const Any &other)
    {
        Any tmp(other);
        swap(tmp);
        return *this;
    }
};

int main()
{
    Any a;
    a = 10;
    int *pa = a.get<int>();
    std::cout << *pa <<std::endl;
    return 0;
}